package io.wit.common.weixin;

import io.wit.common.utils.RedisUtils;
import io.wit.modules.oss.cloud.OSSFactory;
import net.sf.json.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

@Component
public class WeiXinUtil {

    @Autowired
	private RedisUtils redisUtils;

    @Value("${wit.redis.open}")
    private boolean redisOpen;

    // 与接口配置信息中的Token要一致
	private String token = "weixinwit";
	/**
	 * 开发者id
	 */
	//private final String APPID = "wx790315025ccaee7e";
	private final String APPID = "wx97de0fad4e904931";

	public String getAPPID() {
		return APPID;
	}

	/**
	 * 开发者秘钥
	 */
	//private final String APPSECRET = "83797ae377016138593dec98f1b724dc";
	private final String APPSECRET = "5bb83d6317688d8c8537441092ced30b";
	private final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?"
			+ "grant_type=client_credential&appid=APPID&secret=APPSECRET";
	private final String TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
	
	public static String CREATE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";

	/**
	 * 验证签名
	 *
	 * @param signature
	 * @param timestamp
	 * @param nonce
	 * @return
	 */
	public boolean checkSignature(String signature, String timestamp, String nonce) {
		String[] arr = new String[] { token, timestamp, nonce };
		// 将token、timestamp、nonce三个参数进行字典序排序
		Arrays.sort(arr);
		StringBuilder content = new StringBuilder();
		for (int i = 0; i < arr.length; i++) {
			content.append(arr[i]);
		}
		MessageDigest md = null;
		String tmpStr = null;
		try {
			md = MessageDigest.getInstance("SHA-1");
			// 将三个参数字符串拼接成一个字符串进行sha1加密
			byte[] digest = md.digest(content.toString().getBytes());
			tmpStr = byteToStr(digest);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		content = null;
		// 将sha1加密后的字符串可与signature对比，标识该请求来源于微信
		return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
	}

	/**
	 * 将字节数组转换为十六进制字符串
	 *
	 * @param byteArray
	 * @return
	 */
	private String byteToStr(byte[] byteArray) {
		String strDigest = "";
		for (int i = 0; i < byteArray.length; i++) {
			strDigest += byteToHexStr(byteArray[i]);
		}
		return strDigest;
	}

	/**
	 * 将字节转换为十六进制字符串
	 *
	 * @param mByte
	 * @return
	 */
	private String byteToHexStr(byte mByte) {
		char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
		char[] tempArr = new char[2];
		tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
		tempArr[1] = Digit[mByte & 0X0F];
		String s = new String(tempArr);
		return s;
	}

	/**
	 * 处理doget请求
	 * 
	 * @param url
	 * @return
	 */
	public JSONObject doGetstr(String url) {
		CloseableHttpClient httpclient = HttpClients.createDefault();
		HttpGet httpGet = new HttpGet(url);
		JSONObject jsonObject = null;
		try {
			CloseableHttpResponse response = httpclient.execute(httpGet);
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				String result = EntityUtils.toString(entity);
				jsonObject = JSONObject.fromObject(result);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return jsonObject;

	}

	/**
	 * 处理post请求
	 * 
	 * @param url
	 * @return
	 */
	public JSONObject doPoststr(String url, String outStr) {
		CloseableHttpClient httpclient = HttpClients.createDefault();
		HttpPost httpPost = new HttpPost(url);
		JSONObject jsonObject = null;
		try {
			httpPost.setEntity(new StringEntity(outStr, "utf-8"));
			CloseableHttpResponse response = httpclient.execute(httpPost);
			String result = EntityUtils.toString(response.getEntity(), "utf-8");
			jsonObject = JSONObject.fromObject(result);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return jsonObject;
	}

	public void getAccessToken() {
		System.out.println("AccessToken从接口中获取");
		String url = ACCESS_TOKEN_URL.replace("APPID", APPID).replace("APPSECRET", APPSECRET);
		final JSONObject json = doGetstr(url);
		if (json != null) {
			//System.out.println("access_token:"+json.getString("access_token"));
            if(json.containsKey("access_token"))
			redisUtils.set("access_token",json.getString("access_token"),json.getInt("expires_in"));
		}
	}

	/**
	 * 获取凭证
	 * @return
	*/
	public String getAccess_Token(){
	    if(redisOpen){
            String access_token = redisUtils.get("access_token");
            if (access_token == null) {
                getAccessToken();
                access_token = getAccess_Token();
            }
            //System.out.println("access_token:"+access_token);
            return access_token;
        }else{
	        return null;
        }
	}

	/**
	 * @param ticket
	*/
	public void getJsApiTicket(final String access_token) throws Exception {
		System.out.println("ApiTicket从接口中获取");
		if(access_token != null && access_token.length() > 0){
            final String url = TICKET_URL.replace("ACCESS_TOKEN",access_token);
            final JSONObject json = doGetstr(url);
            if (json != null) {
                redisUtils.set("api_ticket", json.getString("ticket"), json.getInt("expires_in"));
            }
        }
	}

	/**
	 * 获取凭证
	 * 
	 * @return
	 * @throws Exception
	 */
	public String getJsApi_Ticket() throws Exception {
		System.out.println("ApiTicket从缓存中读取");
		final String ACCESS_TOKEN = getAccess_Token();
		String ticket_api = redisUtils.get("api_ticket");
		if(!redisOpen){
            return null;
		}
		if (ticket_api == null) {
			getJsApiTicket(ACCESS_TOKEN);
			ticket_api = getJsApi_Ticket();
		}
		return ticket_api;
	}

	public String SHA1(String decript) {
		try {
			MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1");
			digest.update(decript.getBytes());
			byte messageDigest[] = digest.digest();
			// Create Hex String
			StringBuffer hexString = new StringBuffer();
			// 字节数组转换为 十六进制 数
			for (int i = 0; i < messageDigest.length; i++) {
				String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
				if (shaHex.length() < 2) {
					hexString.append(0);
				}
				hexString.append(shaHex);
			}
			return hexString.toString();

		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return "";
	}

	public static String getFileexpandedName(String contentType) {
		String fileEndWitsh = "";
		if ("image/jpeg".equals(contentType))
			fileEndWitsh = ".jpg";
		else if ("audio/mpeg".equals(contentType))
			fileEndWitsh = ".mp3";
		else if ("audio/amr".equals(contentType))
			fileEndWitsh = ".amr";
		else if ("video/mp4".equals(contentType))
			fileEndWitsh = ".mp4";
		else if ("video/mpeg4".equals(contentType))
			fileEndWitsh = ".mp4";
		return fileEndWitsh;
	}

	/**
	 * 获取媒体文件
	 * 
	 * @param accessToken
	 *            接口访问凭证
	 * @param mediaId
	 *            媒体文件id
	 * @param savePath
	 *            文件在本地服务器上的存储路径
	*/
	public String downloadMedia(String mediaId) {
		String accessToken = getAccess_Token();
		String filePath = null;
		// 拼接请求地址
		String requestUrl = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID";
		requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken).replace("MEDIA_ID", mediaId);
		try {
			URL url = new URL(requestUrl);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setDoInput(true);
			conn.setRequestMethod("GET");
			String savePath="D:/upload/";
			// 根据内容类型获取扩展名
			String fileExt = getFileexpandedName(conn.getHeaderField("Content-Type"));
			// 将mediaId作为文件名
			filePath = savePath + mediaId + fileExt;
			BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
			FileOutputStream fos = new FileOutputStream(new File(filePath));
			ByteArrayOutputStream outStream = new ByteArrayOutputStream();
			byte[] buf = new byte[8096];
			int size = 0;
			while ((size = bis.read(buf)) != -1) {
				fos.write(buf, 0, size);
			    outStream.write(buf, 0, size);
			}
			filePath = OSSFactory.build().uploadSuffix(outStream.toByteArray(), fileExt);
			fos.close();
			bis.close();
			conn.disconnect();
			String info = String.format("下载媒体文件成功，filePath=" + filePath);
			System.out.println(info);
		} catch (Exception e) {
			filePath = null;
			String error = String.format("下载媒体文件失败：%s", e);
			System.out.println(error);
		}
		return filePath;
	}
	
	public MenuEntity initMenu(){
		MenuEntity menu = new MenuEntity();

		ViewButtonEntity button1 = new ViewButtonEntity();
		button1.setName("应用中心");
		button1.setType("view");
		button1.setUrl("http://e-3n.com/mobile/index.html"); 
		
		ViewButtonEntity button21 = new ViewButtonEntity();
		button21.setName("三农+简介");
		button21.setType("view");
		button21.setUrl("https://mp.weixin.qq.com/s?__biz=MzIxODI2MTg5OA==&tempkey=OTUwX3VXSGZpV2pTcUh4c1JLWDJWckxtSklZU1ZXQ3JYT2YzOGU1OUE3bUdmOFdGRmd5Z043ZTNadjlSbDBWWUphQnlrbzVneDhoa09tS1I1NW9nR2dobDhXdG1rX3psbk9vek00eHk1dFhUQWZyNWFlUFhjbnVWLXMxbk93SFY4V2pJM0l3YXRHZzBnbnUtVnVmWXBPb1RUVmhXTmg0Snd2T0QtQlhrRHd%2Bfg%3D%3D&#rd");

		ViewButtonEntity button22 = new ViewButtonEntity();
		button22.setName("商家入驻");
		button22.setType("view");
		button22.setUrl("https://mp.weixin.qq.com/s?__biz=MzIxODI2MTg5OA==&tempkey=OTUwX0VEdWFQeURpT2JOYmxoelNWckxtSklZU1ZXQ3JYT2YzOGU1OUE3bUdmOFdGRmd5Z043ZTNadjlSbDBXaUM3b0NzMk8tbDQyRVNtYXN4cDRZSVdUR2p2QWtkWmNtanA4VDZFbTdaaDF2d29LY1VVNFQ4ZFk1QUszWVhoR25RQ0V4aG91cnp2Si11RnlhVUNGdkRPTWlTY0dlcGZ1blh5RDFDY3A3Wmd%2Bfg%3D%3D&#rd"); 
		
		ViewButtonEntity button23 = new ViewButtonEntity();
		button23.setName("合作交流");
		button23.setType("view");
		button23.setUrl("https://mp.weixin.qq.com/s?__biz=MzIxODI2MTg5OA==&tempkey=OTUwX2xVd2V2aDQwc0MwZzE1ODZWckxtSklZU1ZXQ3JYT2YzOGU1OUE3bUdmOFdGRmd5Z043ZTNadjlSbDBVY3ZIZDhHRkhEWEpoTG43MWFOV1p2Tm9KVnZnNWpNZjZHQkFkZ3dMa21iYVhWSUZyR0hTSG92OHkzVWdsMGtJQlljSW5FTTQ4eUJkMHdPTHVQbS1tYjRnTWUwcXBEQ0hJMUtxTV9EZW9TTUF%2Bfg%3D%3D&#rd");

		ButtonEntity button2 = new ButtonEntity();
		button2.setName("三农家"); 
		button2.setSub_button(new ButtonEntity[]{button21,button22,button23});
		
		ViewButtonEntity button31 = new ViewButtonEntity();
		button31.setName("登陆");
		button31.setType("view");
		button31.setUrl("http://e-3n.com/mobile/index.html");
		
		ButtonEntity button3 = new ButtonEntity();
		button3.setName("用户中心"); 
		button3.setSub_button(new ButtonEntity[]{button31});
		menu.setButton(new ButtonEntity[]{button1,button2,button3});

		return menu;

	}
	
	public int createMenu(String menu) throws ClientProtocolException, IOException {
		String accessToken = getAccess_Token();
		int result=0;
		String url=CREATE_MENU_URL.replace("ACCESS_TOKEN", accessToken);
		JSONObject jsonObject= doPoststr(url, menu);
		if(jsonObject != null) {
			result = jsonObject.getInt("errcode");
		}
		return result;

     }
}